/**
 * 
 */
package com.future.controller;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.List;
import java.util.Map.Entry;
import java.util.Properties;

import com.future.common.annotation.ControllerMapping;
import com.future.common.annotation.NoNeedLogin;
import com.future.common.base.BaseController;
import com.jfinal.kit.Ret;
import com.jfinal.plugin.activerecord.Config;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.DbKit;
import com.jfinal.plugin.activerecord.Record;

import lombok.extern.slf4j.Slf4j;

/**
 * @author Leon.Zhang 应用健康检测类
 *
 */
@ControllerMapping("/health")
@Slf4j
public class HealthController extends BaseController {
	@NoNeedLogin
	public void status() {
		String serverInfo = getRequest().getServletContext().getServerInfo();
		Properties props = System.getProperties();

		Ret ret = new Ret();
		ret.set("Status", "UP");
		ret.set("ServerInfo", serverInfo);
		ret.set("OS_Name", props.get("os.name"));
		ret.set("OS_Arch", props.get("os.arch"));
		ret.set("OS_Version", props.get("os.version"));
		ret.set(this.getDbStatus());
		renderJson(ret);
	}

	/**
	 * 获取数据库的状态
	 * 
	 * @return
	 * @throws SQLException 
	 */
	private Ret getDbStatus(){
		Ret ret = new Ret();
		for (Entry<String, Config> configEntry : DbKit.getConfigSet()) {
			String dsName = configEntry.getKey();
			Config config = configEntry.getValue();
			ret.set("DB_" + dsName, "UP");
			Connection connection = null;
			try {
				connection = config.getConnection();
				String sqlString = this.autoCheckValidationQuery(connection.getMetaData().getURL());
				List<Record> result = Db.use(dsName).find(sqlString);
				if (result.size() == 0) {
					ret.set("DB_" + dsName, "DOWN");
				}
			} catch (Exception e) {
				ret.set("DB_" + dsName, "DOWN");
				log.warn("获取数据库信息异常！", e);
			} finally {
				if (connection != null) {
					try {
						connection.close();
					} catch (SQLException e) {
						throw new RuntimeException(e);
					}
				}
			}
		}
		return ret;
	}

	private String autoCheckValidationQuery(String url) {
		if (url.startsWith("jdbc:oracle")) {
			return "select 1 from dual";
		} else if (url.startsWith("jdbc:db2")) {
			return "select 1 from sysibm.sysdummy1";
		} else if (url.startsWith("jdbc:hsqldb")) {
			return "select 1 from INFORMATION_SCHEMA.SYSTEM_USERS";
		} else if (url.startsWith("jdbc:derby")) {
			return "select 1 from INFORMATION_SCHEMA.SYSTEM_USERS";
		}
		return "select 1";
	}
}
